﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Xml;
using AvalonDock;
using ReflectionStudio.Classes;
using ReflectionStudio.Core.Events;
using ReflectionStudio.Core.FTPClient;
namespace ReflectionStudio.Components.UserControls
{
    /// <summary>
    /// DocumentBase is the based class for all Document user controls
    /// </summary>
    public class DocumentBase : DocumentContent
    {
        public DatePicker dateChooser;
        public FTPClient ftpClient = null;
        private WPFExcelReport.BaseFunction m_base;
        TextBox txtftpport
        {
            get
            {
                return (TextBox)this.FindName("txtFTPPort");
            }
        }
        TextBox txtftpsite
        {
            get
            {
                return (TextBox)this.FindName("txtFTPSite");
            }
        }
        TextBox txtftpuser
        {
            get
            {
                return (TextBox)this.FindName("txtFTPUser");
            }
        }
        PasswordBox txtftppwd
        {
            get
            {
                return (PasswordBox)this.FindName("txtFTPPwd");
            }
        }
        #region ----------------CONSTRUCTOR----------------

        /// <summary>
        /// Constructor
        /// </summary>
        public DocumentBase()
        {
            m_base = new WPFExcelReport.BaseFunction();
        }
        public virtual void SetUp(Dictionary<string, object> dicParamater)
        {

        }
        /// <summary>
        /// Plug the load event
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            this.Loaded += new RoutedEventHandler(DocumentBase_Loaded);
        }

        #endregion

        #region ----------------PROPERTIES----------------

        /// <summary>
        /// Document data context
        /// </summary>
        public IDocumentDataContext Context
        {
            get { return this.DataContext as IDocumentDataContext; }
            set { this.DataContext = value; }
        }

        /// <summary>
        /// Content data
        /// </summary>
        public object ContentData { get; set; }

        /// <summary>
        /// Flag property that indicate if the document content is loaded
        /// </summary>
        public bool IsLoaded { get; set; }

        /// <summary>
        /// BackgroundWorker variable
        /// </summary>
        protected BackgroundWorker _Worker = null;

        /// <summary>
        /// Internal BackgroundWorker that can be used for document loading
        /// </summary>
        protected BackgroundWorker Worker
        {
            get
            {
                if (_Worker == null)
                {
                    _Worker = new BackgroundWorker();
                    _Worker.WorkerReportsProgress = false;
                    _Worker.WorkerSupportsCancellation = false;

                }
                return _Worker;
            }
        }

        #endregion

        #region ---------------------LOAD / SAVE---------------------

        virtual public void LoadDocument()
        {
            this.IsLoaded = true;
        }

        virtual public void SaveDocument()
        {
            //			throw new NotImplementedException();
        }

        #endregion

        #region ----------------EVENTS----------------

        void DocumentBase_Loaded(object sender, RoutedEventArgs e)
        {
            Tracer.Verbose("DocumentBase:DocumentBase_Loaded", "START");

            try
            {
                if (!IsLoaded)
                    LoadDocument();
            }
            catch (Exception all)
            {
                Tracer.Error("DocumentBase.DocumentBase_Loaded", all);
            }
            finally
            {
                Tracer.Verbose("DocumentBase:DocumentBase_Loaded", "END");
            }
        }

        /// <summary>
        /// Manage the closing, for exemple saving dirty document
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            return;
        }

        #endregion
        public void SetUpFtp()
        {
            string filePath = @"C:\Windows\intexReportFTP.xml";
            string fileTemp = @"C:\Windows\tempintexReportFTP.xml";
            try
            {
                DataRow dwFTP = null;
                if (System.IO.File.Exists(filePath))
                {
                    RijndaelManaged key = new RijndaelManaged();
                    //设置密钥:key为32位=数字或字母16个=汉字8个
                    byte[] byteKey = Encoding.Unicode.GetBytes("1111111111111111");
                    key.Key = byteKey;
                    // Load an XML document.
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.PreserveWhitespace = true;
                    xmlDoc.Load(filePath);
                    Decrypt(xmlDoc, key);
                    DataSet setFTP = new DataSet();
                    xmlDoc.Save(fileTemp);
                    setFTP.ReadXml(fileTemp);
                    if (File.Exists(fileTemp))
                    {
                        File.Delete(fileTemp);
                    }
                    if (setFTP.Tables.Count > 0)
                    {
                        if (setFTP.Tables[0].Rows.Count > 0)
                        {
                            dwFTP = setFTP.Tables[0].Rows[0];
                            txtftpsite.Text = dwFTP["FTPSite"].ToString();
                            txtftpport.Text = dwFTP["FTPPort"].ToString();
                            txtftpuser.Text = dwFTP["FTPUser"].ToString();
                            txtftppwd.Password = dwFTP["FTPPwd"].ToString();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }

        public void SaveFtp(string FTPSite, string FTPPort, string FTPUser, string FTPPwd, bool isAdmin = false)
        {
            try
            {
                string filePath = @"C:\Windows\intexReportFTP.xml";
                string fileTemp = @"C:\Windows\tempintexReportFTP.xml";
                if (ftpClient != null)
                {
                    DataSet setFTP = new DataSet("FTPSet");
                    DataTable ftpTable = new DataTable("FTPTable");
                    ftpTable.Columns.Add(new DataColumn("FTPSite", typeof(string)));
                    ftpTable.Columns.Add(new DataColumn("FTPPort", typeof(string)));
                    ftpTable.Columns.Add(new DataColumn("FTPUser", typeof(string)));
                    ftpTable.Columns.Add(new DataColumn("FTPPwd", typeof(string)));
                    DataRow dwFtp = ftpTable.Rows.Add();
                    dwFtp["FTPSite"] = FTPSite.Trim();
                    dwFtp["FTPPort"] = FTPPort.ToString().Trim();
                    dwFtp["FTPUser"] = FTPUser.Trim();
                    dwFtp["FTPPwd"] = FTPPwd.Trim();
                    setFTP.Tables.Add(ftpTable);
                    setFTP.WriteXml(fileTemp);
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.PreserveWhitespace = true;
                    xmlDoc.Load(fileTemp);
                    RijndaelManaged key = new RijndaelManaged();
                    //设置密钥:key为32位=数字或字母16个=汉字8个
                    byte[] byteKey = Encoding.Unicode.GetBytes("1111111111111111");
                    key.Key = byteKey;
                    Encrypt(xmlDoc, "FTPPwd", key);
                    if (File.Exists(fileTemp))
                    {
                        File.Delete(fileTemp);
                    }
                    xmlDoc.Save(filePath);
                }
                else
                {
                    MessageBox.Show("请输入正确的FTP信息");
                }
                // Encrypt the "creditcard" element.


            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }

        public void CheckFtp(string ftpsite, string ftpport, string ftpuser, PasswordBox txtFTPPwd, bool isAdmin = false, string ftppwd = "")
        {
            try
            {
                string FTPSite = ftpsite;
                int FTPPort = System.Convert.ToInt16(ftpport);
                string FTPUser = ftpuser;
                System.Security.SecureString sPassword = txtFTPPwd.SecurePassword;
                IntPtr p = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(sPassword);
                string FTPPwd = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p);
                if (ftppwd != "")
                {
                    FTPPwd = ftppwd;
                }
                ftpClient = new FTPClient(FTPSite, FTPPort, FTPUser, FTPPwd);

                ftpClient.Open();
                ftpClient.Login();
                SaveFtp(FTPSite, FTPPort.ToString(), FTPUser, FTPPwd, isAdmin);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }
        public static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key)
        {
            try
            {
                XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;
                EncryptedXml eXml = new EncryptedXml();
                byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
                EncryptedData edElement = new EncryptedData();
                edElement.Type = EncryptedXml.XmlEncElementUrl;
                string encryptionMethod = null;

                if (Key is TripleDES)
                {
                    encryptionMethod = EncryptedXml.XmlEncTripleDESUrl;
                }
                else if (Key is DES)
                {
                    encryptionMethod = EncryptedXml.XmlEncDESUrl;
                }
                if (Key is Rijndael)
                {
                    switch (Key.KeySize)
                    {
                        case 128:
                            encryptionMethod = EncryptedXml.XmlEncAES128Url;
                            break;
                        case 192:
                            encryptionMethod = EncryptedXml.XmlEncAES192Url;
                            break;
                        case 256:
                            encryptionMethod = EncryptedXml.XmlEncAES256Url;
                            break;
                    }
                }
                edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
                edElement.CipherData.CipherValue = encryptedElement;
                EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }

        public static void Decrypt(XmlDocument Doc, SymmetricAlgorithm Alg)
        {
            try
            {
                XmlElement encryptedElement = Doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;
                EncryptedData edElement = new EncryptedData();
                edElement.LoadXml(encryptedElement);
                EncryptedXml exml = new EncryptedXml();
                byte[] rgbOutput = exml.DecryptData(edElement, Alg);
                exml.ReplaceData(encryptedElement, rgbOutput);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }
    }
}